package chat;

import java.io.*;
import java.net.*;
import java.util.*;

public class ConcurrentChatServer implements Runnable  {
  Thread listener;
  ServerSocket server;
  Vector connections = new Vector();

  public static void main(String args[]) {
    new ConcurrentChatServer();
  }

  public ConcurrentChatServer () {
    try {
      server = new ServerSocket(7);
      listener = new Thread(this);
      listener.start();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  public void run() {
    try {
      while(true) {
        Socket client = server.accept();
        ChatClient c = new ChatClient(this, client);
        c.start();
        connections.addElement(c);
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  public synchronized void broadcast(String message) {
    for(int i=0; i < connections.size(); i++) {
      ((ChatClient)connections.elementAt(i)).send(message);
    }
  }

  public synchronized void closeConnection(ChatClient client) {
    connections.remove(client);
  }
}

class ChatClient extends Thread {
  Socket s;
  DataOutputStream out;
  DataInputStream in;
  ConcurrentChatServer server;

  public ChatClient(ConcurrentChatServer server, Socket s) throws IOException {
    this.server = server;
    this.s = s;
    out = new DataOutputStream(s.getOutputStream());
    in = new DataInputStream(s.getInputStream());
  }

  public void run() {
    String text;
    try {
      while((text = in.readUTF()) != null) {
        server.broadcast(text);
      }
    }
    catch(IOException e) {
      e.printStackTrace();
    }
    server.closeConnection(this);
  }

  public void send(String message) {
    try {
      out.writeUTF(message);
    }
    catch(IOException e) {
      e.printStackTrace();
    }
  }
}